/***********************************************************************
 * nScreen - An Advanced Console Application Framework for .NET
 * 
 * Copyright (C) 2007 by:
 *  Justin Long (dukk(a)dukk.org)
 *  Fabio Cavalcante (fabio(a)codesapien.com)
 *  Josh Perry (josh(a)6bit.com)
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as 
 * published by  the Free Software Foundation; either version 2 of the 
 * License or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this package (See COPYING.LIB); if not, write to the 
 * Free Software Foundation, Inc.
 * 59 Temple Place - Suite 330
 * Boston, MA 02111-1307, USA.
 ***********************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace nScreen.Controls
{
	public class ScreenControlCollection : ICollection<ScreenControl>
	{
		private List<ScreenControl> _controls;

		public event EventHandler<ScreenControlEventArgs> ControlAdded;
		public event EventHandler<ScreenControlEventArgs> ControlRemoved;
		public event EventHandler<ScreenControlCollectionClearedEventArgs> Cleared;

		public ScreenControlCollection()
		{
			_controls = new List<ScreenControl>();
		}

		public int Count
		{
			get { return _controls.Count; }
		}

		public bool IsReadOnly
		{
			get { return false; }
		}

		public bool Remove(ScreenControl control)
		{
			bool result = _controls.Remove(control);

			if (result)
			{
				this.OnControlRemoved(control);
			}

			return result;
		}

		public void Add(ScreenControl control)
		{
			if (control is Screen)
			{
				throw new InvalidOperationException("You can not add a screen to the ScreenControlCollection.");
			}

			_controls.Add(control);

			this.OnControlAdded(control);
		}

		public void Clear()
		{
			ScreenControl[] controlsCleared = new ScreenControl[0];

			_controls.CopyTo(controlsCleared);

			_controls.Clear();

			this.OnCleared(controlsCleared);
		}

		public bool Contains(ScreenControl control)
		{
			return _controls.Contains(control);
		}

		public void CopyTo(ScreenControl[] array, int arrayIndex)
		{
			_controls.CopyTo(array, arrayIndex);
		}

		public IEnumerator<ScreenControl> GetEnumerator()
		{
			return _controls.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return ((IEnumerable)_controls).GetEnumerator();
		}

		protected virtual void OnControlAdded(ScreenControl control)
		{
			EventHandler<ScreenControlEventArgs> handler = this.ControlAdded;
			ScreenControlEventArgs e = new ScreenControlEventArgs(control);

			if (null != handler)
			{
				handler(this, e);
			}
		}

		protected virtual void OnControlRemoved(ScreenControl control)
		{
			EventHandler<ScreenControlEventArgs> handler = this.ControlRemoved;
			ScreenControlEventArgs e = new ScreenControlEventArgs(control);

			if (null != handler)
			{
				handler(this, e);
			}
		}

		protected virtual void OnCleared(ScreenControl[] controlsCleared)
		{
			EventHandler<ScreenControlCollectionClearedEventArgs> handler = this.Cleared;
			ScreenControlCollectionClearedEventArgs e = new ScreenControlCollectionClearedEventArgs(controlsCleared);

			if (null != handler)
			{
				handler(this, e);
			}
		}
	}
}